package main

import (
	"encoding/json"
	"fmt"
	"log"
	"sort"

	"go.etcd.io/bbolt"
)

// DeviceData 代表 device_data 表中的一行数据
type DeviceData struct {
    ID   int    `json:"id"`
    Name string `json:"name"`
    Data string `json:"data"`
}

func main() {
    // 打开 bbolt 数据库
    boltDB, err := bbolt.Open("../openGW_bbolt.db", 0755, nil)
    if err != nil {
        log.Fatal(err)
    }
    defer boltDB.Close()

    // // 根据 ID 查询最新的 
    // latestDevices, err := queryLatestDevicesByID(boltDB, 100)
    // if err != nil {
    //     log.Fatalf("查询最新设备数据失败: %v", err)
    // }
 	 //  fmt.Printf("最新的 1000 条设备数据:\n%+v\n", latestDevices)


	fmt.Println("-----------------------------------------------------------------------------------")

    // 示例：根据设备名称查询最新一条数据
    deviceName := "电表2a" // 示例设备名称
    latestDevice, err := queryDevicesByName(boltDB, deviceName, 1)
    if err != nil {
        log.Fatalf("查询最新设备数据失败: %v", err)
    }
    fmt.Printf("设备名称为 '%s' 的最新一条数据:\n%+v\n", deviceName, latestDevice)

    // 示例：根据设备名称查询所有数据
    allDevices, err := queryDevicesByName(boltDB, deviceName, 2)
    if err != nil {
        log.Fatalf("查询所有设备数据失败: %v", err)
    }
    fmt.Printf("设备名称为 '%s' 的所有数据:\n%+v\n", deviceName, allDevices)

    // 示例：根据设备名称查询最新的 5 条数据
    latestFiveDevices, err := queryDevicesByName(boltDB, deviceName, 5)
    if err != nil {
        log.Fatalf("查询最新 5 条设备数据失败: %v", err)
    }
    fmt.Printf("设备名称为 '%s' 的最新 5 条数据:\n%+v\n", deviceName, latestFiveDevices)
}

// queryLatestDevicesByID 根据 ID 查询最新的 n 条数据
func queryLatestDevicesByID(db *bbolt.DB, n int) ([]DeviceData, error) {
    var devices []DeviceData

    // 在读取事务中获取数据
    err := db.View(func(tx *bbolt.Tx) error {
        // 获取 device_data 的 bucket
        bucket := tx.Bucket([]byte("device_data"))
        if bucket == nil {
            return fmt.Errorf("bucket 'device_data' 不存在")
        }

        // 遍历 bucket 中的所有键值对
        err := bucket.ForEach(func(k, v []byte) error {
            var device DeviceData
            if err := json.Unmarshal(v, &device); err != nil {
                return err
            }
            devices = append(devices, device)
            return nil
        })
        return err
    })
    if err != nil {
        return nil, err
    }

    // 按照 ID 降序排序
    sort.Slice(devices, func(i, j int) bool {
        return devices[i].ID > devices[j].ID
    })

    // 返回最新的 n 条数据
    if len(devices) > n {
        devices = devices[:n]
    }
    return devices, nil
}

// queryDevicesByName 根据设备名称查询所有匹配的数据
// 参数:
// - db: bbolt 数据库对象
// - name: 设备名称
// - limit: 获取的数据条数，0 表示获取全部匹配的数据
func queryDevicesByName(db *bbolt.DB, name string, limit int) ([]DeviceData, error) {
    var matchedDevices []DeviceData

    // 在读取事务中获取数据
    err := db.View(func(tx *bbolt.Tx) error {
        // 获取 device_data 的 bucket
        bucket := tx.Bucket([]byte("device_data"))
        if bucket == nil {
            return fmt.Errorf("bucket 'device_data' 不存在")
        }

        // 遍历 bucket 中的所有键值对
        err := bucket.ForEach(func(k, v []byte) error {
            var device DeviceData
            if err := json.Unmarshal(v, &device); err != nil {
                return err
            }

            // 检查设备名称是否匹配
            if device.Name == name {
                matchedDevices = append(matchedDevices, device)
            }
            return nil
        })
        return err
    })
    if err != nil {
        return nil, err
    }

    // 按照 ID 降序排序（最新的数据在前）
    sort.Slice(matchedDevices, func(i, j int) bool {
        return matchedDevices[i].ID > matchedDevices[j].ID
    })

    // 根据 limit 返回数据
    if limit > 0 && len(matchedDevices) > limit {
        return matchedDevices[:limit], nil
    }
    return matchedDevices, nil
}